import { Callout, Sandpack } from '@/components'

# queryOptions

<Callout type='warning'>

**Deprecated in @suspensive/react-query**

This interface is now officially supported in TanStack Query v4.40.0+. Since TanStack Query has backported this interface, we are deprecating the backported version from @suspensive/react-query. Please migrate to the official TanStack Query interface:

```diff
- import { queryOptions } from '@suspensive/react-query'
+ import { queryOptions } from '@tanstack/react-query'
```

For more details, see [TanStack Query PR #9140](https://github.com/TanStack/query/pull/9140).

</Callout>

Tkdodo, The maintainer of TanStack Query explains well why this interface is needed in [video explaining queryOptions in TanStack Query v5](https://youtu.be/bhE3wuB_TuA?feature=shared&t=1697).
You can also use queryOptions in TanStack Query v4.

1. QueryKey management becomes easier by processing queryKey and queryFn together.
2. You can remove unnecessary custom query hooks. This is because they can all be used directly in `useQuery`, `useQueries` of TanStack Query v4, and `useSuspenseQuery`, `useSuspenseQueries`, and `SuspenseQuery` of Suspensive React Query.
3. TanStack Query v5 already supports queryOptions. This Suspensive React Query's `queryOptions` will make migration from TanStack Query v4 to TanStack Query v5 easier.

```jsx /queryOptions/
import { queryOptions, useSuspenseQuery, useSuspenseQueries, SuspenseQuery } from '@suspensive/react-query'
import { useQuery, useQueries, useQueryClient } from '@tanstack/react-query'

const postQueryOptions = (postId) =>
   queryOptions({
     queryKey: ['posts', postId] as const,
     queryFn: ({
       queryKey: [, postId], // You can use queryKey.
     }) => fetch(`https://example.com/posts/${postId}`),
   })

// No need to create custom query hooks.
// You can use queryOptions directly in useQuery, useQueries, useSuspenseQuery, useSuspenseQueries, SuspenseQuery.
const post1Query = useQuery(postQueryOptions(1))
const { data: post1 } = useSuspenseQuery({
   ...postQueryOptions(1);
   refetchInterval: 2000, // Extensibility is clearly expressed in usage.
})
const [post1Query, post2Query] = useQueries({
   queries: [postQueryOptions(1), { ...postQueryOptions(2), refetchInterval: 2000 }],
})
const [{ data: post1 }, { data: post2 }] = useSuspenseQueries({
   queries: [postQueryOptions(1), { ...postQueryOptions(2), refetchInterval: 2000 }],
})
const Example = () => <SuspenseQuery {...postQueryOptions(1)}>{({ data: post1 }) => <>{post1.text}</>}</SuspenseQuery>

// You can easily use queryKey and queryFn in queryClient's methods.
const queryClient = useQueryClient()
queryClient.refetchQueries(postQueryOptions(1))
queryClient.prefetchQuery(postQueryOptions(1))
queryClient.invalidateQueries(postQueryOptions(1))
queryClient.fetchQuery(postQueryOptions(1))
queryClient.resetQueries(postQueryOptions(1))
queryClient.cancelQueries(postQueryOptions(1))

```

<Sandpack>

```tsx Example.tsx active
import { Suspense } from '@suspensive/react'
import { queryOptions, SuspenseQuery } from '@suspensive/react-query'
import { useQueryClient } from '@tanstack/react-query'
import { getPost } from './api'

const postQueryOptions = (postId: number) =>
  queryOptions({
    queryKey: ['posts', postId],
    queryFn: () => getPost(postId),
  })

export const Example = () => {
  const queryClient = useQueryClient()

  return (
    <div>
      <button onClick={() => queryClient.resetQueries(postQueryOptions(1))}>
        Reset Query
      </button>
      <Suspense fallback={<div>Loading...</div>}>
        <SuspenseQuery {...postQueryOptions(1)}>
          {({ data }) => {
            return (
              <div>
                <h1>{data.title}</h1>
                <p>{data.body}</p>
              </div>
            )
          }}
        </SuspenseQuery>
      </Suspense>
    </div>
  )
}
```

```tsx api.ts
type Post = {
  userId: number
  id: number
  title: string
  body: string
}

export const getPost = async (id: number): Promise<Post> => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  )

  if (!response.ok) {
    throw new Error('An error occurred')
  }

  const data = await response.json()

  return data
}
```

</Sandpack>

### Version History

| Version  | Changes                                                                                                                       |
| -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `v3.0.0` | `networkMode` has been removed. For more details, please refer to the [Migration to v3 guide](./migration/migrate-to-v3.mdx). |
